package Server;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;

import Common.Constants;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class AlibabaServer {

	// GLOBAL VARS.


	// local storage dir.
	static String BULib;

	public static ServerService aliService;


	public static void main(String[] args) {

		// INPUT CHECK
		if (args.length != 0){
			BULib = args[0] + File.separator ;
		}
		else {
			System.out.println("usage: alibabaServer <Backup Directory Name>");
			return;
		}


		aliService = new myServerService();
		aliService.init(BULib);

		// create a connection
		InetSocketAddress addr = new InetSocketAddress(8080);
		HttpServer server;
		try {
			server = HttpServer.create(addr, 0);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("failed to start server");
			return;
		}

		server.createContext("/", new MyHandler());
		server.start();
		System.out.println("Server is listening on port 8080");
	}
}

class MyHandler implements HttpHandler {	
	public void handle(HttpExchange exchange){
		String requestMethod = exchange.getRequestMethod();
		String requestAuth = exchange.getRequestHeaders().getFirst("Authorization");
		if (requestAuth == null){
			ServerUtils.sendBadRequestMsg(exchange);
			return;
		}
		String userName = requestAuth;

		Headers responseHeaders = exchange.getResponseHeaders();
		responseHeaders.set("Content-Type", "text/plain");




		// GET REQUEST
		if (requestMethod.equalsIgnoreCase("GET")) {

			URI url = exchange.getRequestURI();
			String query = url.getQuery();
			String fileName = url.getPath(); 

			if((query == null) || (query.startsWith(Constants.SNAPSHOT))){		//restore a file/directory	
				int snapshot = ServerUtils.parseSnapshot(query);

				if (ServerUtils.isDir(fileName)){		//this is a list dir. request
					AlibabaServer.aliService.listDir(fileName, userName, snapshot, exchange);
				}
				else{ 		// the is a file restore request
					AlibabaServer.aliService.restoreFile(userName, fileName, snapshot, exchange);
				}
			}
			else if(query.equals(Constants.SIGNATURE)){		//signature get request
				AlibabaServer.aliService.getSignature(fileName, userName, exchange);
			}
			else if(query.equals(Constants.CHECK)){			//check and validate
				ServerUtils.debugMsg("User: " + userName + " wants to do a checkup on directory: " + fileName);
				AlibabaServer.aliService.check(fileName, userName, exchange);
			}

			else{		//future use, probably want to parse variables
				//Map<String, String> nameAndValueMap = ServerUtils.getQueryMap(query);
			}

		}

		// PUT REQUEST
		else if(requestMethod.equalsIgnoreCase("PUT")){
			URI url = exchange.getRequestURI();
			String query = url.getQuery();
			String fileName = url.getPath();

			synchronized(this){
				if (query != null){
					if (query.startsWith(Constants.SNAPSHOT)){
						// (---CREATE SNAPSHOT---)
						//basically all we need is to go over all user files from working copy and add the intID
						int snapshotID = ServerUtils.parseSnapshot(query);
						AlibabaServer.aliService.createSnapshot(exchange, userName, snapshotID);
					}
					else if (query.startsWith(Constants.SIGNATURE)){	
						// (---BACKUP WITH SIGNATURE---)
						String B64signature = query.substring(query.indexOf('=')+1).trim();	//in Base64
						byte[] signature = null;
						try {
							signature = Common.Base64.decode(B64signature, Common.Base64.URL_SAFE);
						} catch (IOException e) {
							e.printStackTrace();
							ServerUtils.sendInternErrMsg(exchange);
						} 
						AlibabaServer.aliService.backupWithSignature(exchange, userName, fileName, signature);
					}
				}
				else { //HERE WE KNOW THAT A NEW FILE WILL BE SAVED ON DISK
					AlibabaServer.aliService.backupWithData(exchange, userName, fileName);
				}//here is end of synchronization
			}
		}	//end of "GET" condition
		else if(requestMethod.equalsIgnoreCase("DELETE")){
			URI url = exchange.getRequestURI();
			String query = url.getQuery();
			int snapshotID;

			if (query != null){
				if (query.startsWith(Constants.SNAPSHOT)){//http://localhost:8080/oded?snapshot=5
					snapshotID = ServerUtils.parseSnapshot(query);
					AlibabaServer.aliService.deleteSnapshot(exchange, userName, snapshotID);
				}
				else{
					ServerUtils.sendInternErrMsg(exchange);
				}
			}
		}// end of "DELETE" condition	
	}
}